#ifndef _SNAKE_DEFINE_H
#define _SNAKE_DEFINE_H


#include "main.h"


//C++ Snake 合适的数据结构——队列（蛇的坐标位置）
//（变化的时候, 只会在蛇头处插入（队列尾）， 蛇尾处删除或者不变(队列头)
class Snake
{
public:
    Snake(int socket_fd=0, GameStat stat=GAME_MENU)
    {
        m_playinfo.m_score = 0;
        m_playinfo.m_socket_fd = 0;
        m_playinfo.m_stat = stat;
    }
    /*
    *@func:构造函数
    *@param：bev参数必须输入，其他参数可选（有默认值）。
    */
    Snake(struct bufferevent *bev)
    {
        m_playinfo.bev = bev;
        m_playinfo.m_score = 0;
        m_playinfo.m_socket_fd = 0;
        m_playinfo.m_stat = GAME_MENU;//一开始的状态为GAME_MEMU,此时不应该发送地图信息给客户端。        
    }

    ~Snake()
    {

    }

    bool operator==(const Snake& other) const {
        return other.m_playinfo.bev == this->m_playinfo.bev; 
    }

    void build_head_body(int x=10, int y=10, SnakeDir dir = RIGHT, int length=5)
    {
        //初始化蛇头（默认蛇头初始位置[10,10]，方向向右）
        SnakeNode temp_node = {0};
        temp_node.dir = dir;
        temp_node.x = x;
        temp_node.y = y;
        m_snake.push_front(temp_node);

        //初始化一段蛇身（默认长度为5）
        for(int i=0; i<length-1; i++)
        {
            temp_node.x--;
            m_snake.push_back(temp_node);
        }
    }


    void create_a_valid_snake();

    bool isGameOver()
    {
        return (m_playinfo.m_stat==GAME_OVER);
    }
    bool isGameStarted()
    {
        return (m_playinfo.m_stat == GAME_STARTED);
    }
    SnakeNode& get_snake_head()//返回的是一个引用
    {
        //return m_snake.back();//队列尾是蛇头
        #ifdef DEBUG_MODE
        std::cout << "\n\nget_snake_head:  "<<m_snake.size() <<std::endl;
        std::cout <<std::endl;
        #endif

        return m_snake.front();//双端队列头是蛇头
    }

    struct bufferevent * get_snake_evp()
    {
        return m_playinfo.bev;
    }


    void snake_move(void); //defined in data_process.cpp
    void renew_snake_head(SnakeNode head)
    {
        std::cout << "before push: snake's size: "<< m_snake.size() << std::endl;
        m_snake.push_front(head);
        std::cout << "after push: snake's size: "<< m_snake.size() << std::endl;
    }
    void remove_snake_tail();
    
    bool isEatFood();//判断当前蛇是否吃到了食物


    void set_user_stat(GameStat stat)
    {
        m_playinfo.m_stat = stat;
    }
    void set_snake_head_dir(SnakeDir dir)
    {
        //SnakeNode head = get_snake_head();//这里初始化一个head，执行的是复制操作，这个新建的head相当于与原来的head无关。
        SnakeNode &head = get_snake_head();
        head.dir = dir;
    }

    std::deque<SnakeNode> & get_snake_total()
    {
        return m_snake;
    }

    int get_snake_len(void)
    {
        return m_snake.size();
    }

    unsigned char get_snake_score(void)
    {
        return m_playinfo.m_score;
    }

    void set_snake_speed()
    {

    }
    void snake_die();
    void add_user_score(int score = 1)
    {
        m_playinfo.m_score += score;
    }
    void check_hit_wall();
    void check_hit_other();
    void check_hit_self();
    
    bool check_birth_valid();
private:
    //std::queue<SnakeNode> snake_node_list;
    std::deque<SnakeNode> m_snake;/*蛇本身的信息*/
    PlayerInfo m_playinfo;/*用户相关的信息*/
};


#endif